import time
import logging
from binance.lib.utils import config_logging
from binance.websocket.um_futures.websocket_client import UMFuturesWebsocketClient
from util.UTILS import *
import json
from binance.um_futures import UMFutures

from util.ExchangeCommon import *
from deal.funding_rate_interest_arbitrage.exception.depth_exception import *

class binance_exchange:

    def __init__(self,exchange_key,exchange_secret):
        self.future_client = UMFuturesWebsocketClient(on_message=self.message_handler,on_close=self.UMFuturesWebsocketClient_onclose_handler)
        self.logger = getLogger("binance")


        self.um_futures_client = UMFutures(key=exchange_key, secret=exchange_secret)
        self.symbol_list = self.um_futures_client.exchange_info()
        self.depth = {}
        time.sleep(4)


    def get_order(self,symbol,order_id):
        return self.um_futures_client.query_order(symbol=symbol, orderId=order_id, recvWindow=3000)

    def message_handler(self,_,message):
        message_obj = json.loads(message)
        if message_obj['s']:
            _symbol = message_obj['s']
            self.depth[_symbol] = json.loads(message)

    def get_account_info(self,symbol):
        balances = self.um_futures_client.balance(recvWindow=90000)
        useBanlance = None
        for balance in balances:
            if balance['asset'] == symbol:
                useBanlance = balance
        # return Account(Info=useBanlance, Balance=useBanlance['availableBalance'], FrozenBalance=None, Stocks=None,
        #                FrozenStocks=None)
        return float(useBanlance['availableBalance'])

    def get_positions(self,symbol):
        accounts = self.um_futures_client.account()
        positions = accounts['positions']
        for postion in positions:
            if postion['symbol'] == symbol:
                return postion

        return

    def get_all_positions(self):
        accounts = self.um_futures_client.account()
        return accounts['positions']



    def place_order_market(self,symbol,side,quantity,order_type='MARKET'):
        params = {
            'symbol': symbol,
            'side': side,
            'type': order_type,
            'quantity': quantity,  # 这里需要根据币安的精度要求进行调整
        }
        return self.um_futures_client.new_order(**params, recvWindow=4000)



    def UMFuturesWebsocketClient_onclose_handler(self,*args):
        self.future_client = UMFuturesWebsocketClient(on_message=self.message_handler,on_close=self.UMFuturesWebsocketClient_onclose_handler)
        self.subscribe()

    def get_depth(self,symbol):
        if self.depth[symbol]:
            depth_update_time = self.depth[symbol]['E']
            new_time = round(time.time() * 1000)
            # 检查 深度数据更新时间是否大于 4秒
            if new_time - depth_update_time > 4 * 1000:
                # self.logger.info(f"get_depth data time out  ,data time : {millisecond_2_date_str(depth_update_time)}    now_time:{millisecond_2_date_str(new_time)}   chae :{new_time - depth_update_time}")
                print(f"get_depth data time out  ,data time : {millisecond_2_date_str(depth_update_time)}    now_time:{millisecond_2_date_str(new_time)}   chae :{new_time - depth_update_time}")
                #重连
                self.UMFuturesWebsocketClient_onclose_handler()
                time.sleep(2)
                #重新订阅
                self.subscribe(symbol)
                time.sleep(1)
                raise depth_update_exception(f"depth_update_time 检查超时  {symbol}")
            return self.depth[symbol]


    def subscribe(self,symbol):
        self.future_client.partial_book_depth(
            symbol=symbol,
            level=10,
            speed=100,
        )


if __name__ == '__main__':
    # 夸所 套资金费率
    key = "3S4j9rBxss0KBivifkgMMEykgWad9GEMl9hdgMhViiwKGNDy5NoLkYHIDg6K3VU5"
    secret = "NzWj2BnVToddcO39tkJp7N1Xz041EYwzgVibMV7czf0ZaHWfuCM8GHnO8pBp03xH"
    exchange = binance_exchange(key,secret)

    balance = exchange.get_account_info("USDT")
    print(balance)
    # time.sleep(2)
    # exchange.subscribe("OMGUSDT")
    # time.sleep(5)
    # while True:
    #     try:
    #         depth = exchange.get_depth("OMGUSDT")
    #         # b 买方  a 是卖方
    #         print(f"{millisecond_2_date_str(depth['E'])}  symbol:{depth['s']}  buy 1:{depth['b'][0][0]}     sell 1 :{depth['a'][0][0]}")
    #     except depth_update_exception as e:
    #         print("depth_update_exception ****************")
    #         exchange.UMFuturesWebsocketClient_onclose_handler('')
    #         time.sleep(5)
    #     time.sleep(0.5)